package com.a.b.c.d.e.utils;

import com.a.b.c.d.e.entities.BollAndCciDataEntity;
import com.a.b.c.d.e.entities.DataEntity;
import com.a.b.c.d.e.entities.KLinesEntity;
import org.springframework.util.CollectionUtils;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Created on 2021/10/8.
 *
 * @author yanshuchun
 */
public class EastMoneyUtil {
    private static final String def_referer = "http://data.eastmoney.com/";

    public static void main(String[] args) {


    }

    public static String getDataFromEastMoney(String baseUrl, Map<String, String> params, String referer) {
        String response = null;
        try {
            URL url = new URL(baseUrl + mapToUrlString(params));
            HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
            httpConn.setRequestMethod("GET");
            httpConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:92.0) Gecko/20100101 Firefox/92.0");
            httpConn.setRequestProperty("Accept", "*/*");
            httpConn.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
            httpConn.setRequestProperty("DNT", "1");
            httpConn.setRequestProperty("Connection", "keep-alive");
            httpConn.setRequestProperty("Referer", referer == null ? def_referer : referer);
            httpConn.setRequestProperty("Pragma", "no-cache");
            httpConn.setRequestProperty("Cache-Control", "no-cache");
            httpConn.setRequestProperty("Cookie", "em_hq_fls=js; HAList=f-0-000001-%u4E0A%u8BC1%u6307%u6570; qgqp_b_id=2ec8296ad6c6e46a1b54f86ac5c9c812; st_si=60577181979583; st_sn=9; st_psi=20211008095403709-113300301471-1472542649; st_asi=delete; cowCookie=true; intellpositionL=1522.4px; intellpositionT=1364px; cowminicookie=true; st_pvi=19958116574134; st_sp=2021-09-27%2014%3A51%3A33; st_inirUrl=https%3A%2F%2Fwww.baidu.com%2Flink");
            InputStream responseStream = httpConn.getResponseCode() / 100 == 2
                    ? httpConn.getInputStream()
                    : httpConn.getErrorStream();
            Scanner s = new Scanner(responseStream).useDelimiter("\\A");
            response = s.hasNext() ? s.next() : "";

        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return response;
    }


    public static String mapToUrlString(Map<String, String> map) {
        StringBuilder sb = new StringBuilder();
        Set set = map.keySet();
        set.stream().forEach(item -> {
            sb.append(item + "=" + map.get(item) + "&");
        });
        String s = sb.toString();
        return s.substring(0, s.length() - 1);
    }

    public static KLinesEntity stringToKLinesEntity(String string) {
        List<String> gupiaoEntityList = Arrays.asList(string.split(","));
        KLinesEntity kLinesEntity = new KLinesEntity();
        kLinesEntity.setDate(gupiaoEntityList.get(0));
        kLinesEntity.setKp(new Double(gupiaoEntityList.get(1)));
        kLinesEntity.setSp(new Double(gupiaoEntityList.get(2)));
        kLinesEntity.setTop(new Double(gupiaoEntityList.get(3)));
        kLinesEntity.setLow(new Double(gupiaoEntityList.get(4)));
        kLinesEntity.setZdf(gupiaoEntityList.get(8) + "%");
        kLinesEntity.setZde(new Double(gupiaoEntityList.get(9)));
        kLinesEntity.setCjl(new Double(new DecimalFormat("#.00").format(new Double(gupiaoEntityList.get(5)) / 10000)));
        kLinesEntity.setCje(new Double(new DecimalFormat("#.00").format(new Double(gupiaoEntityList.get(6)) / 10000)));
        kLinesEntity.setZf(gupiaoEntityList.get(7) + "%");
        kLinesEntity.setHsl(gupiaoEntityList.get(10) + "%");
        return kLinesEntity;
    }

    /**
     * @param kLinesEntities
     * @param yz
     */
    public static List<DataEntity> cci(List<KLinesEntity> kLinesEntities, Integer yz, Integer current, List<DataEntity> res) {
        if (kLinesEntities.size() - current < yz) {
            return res;
        } else {
            Double tp = 0.0;
            Double ma = 0.0;
            AtomicReference<Double> md_temp = new AtomicReference<>(0.0);
            List<Double> doubles = new ArrayList<>();
            KLinesEntity kLinesEntity_ = new KLinesEntity();
            for (int i = current; i < yz + current; i++) {
                KLinesEntity kLinesEntity = kLinesEntities.get(kLinesEntities.size() - i - 1);
                if (current == i) {
                    kLinesEntity_ = kLinesEntity;
                    tp += kLinesEntity.getTop();
                    tp += kLinesEntity.getLow();
                    tp += kLinesEntity.getSp();
                    tp = tp / 3;
                }
                ma += kLinesEntity.getSp();
                doubles.add(kLinesEntity.getSp());
            }
            ma = ma / yz;
            Double finalMa = ma;
            doubles.stream().forEach(item -> {
                Double temp = finalMa-item;
                if (temp < 0) {
                    temp = Math.sqrt(Math.pow(temp,2));
                }
                Double finalTemp = temp;
                md_temp.updateAndGet(v -> v + finalTemp);
            });
            Double md = md_temp.get();
            md = md/yz;
            DataEntity cciDataEntity = new DataEntity();
            cciDataEntity.setDate(kLinesEntity_.getDate());
            cciDataEntity.setData((tp - ma) / md / 0.015);
            res.add(cciDataEntity);
            return cci(kLinesEntities, yz, current + 1, res);
        }
    }

    public static BollAndCciDataEntity boll(List<KLinesEntity> kLinesEntities, Integer yz, Integer current, BollAndCciDataEntity res) {
        if (kLinesEntities.size() - current < yz) {
            return res;
        } else {
            Double ma = 0.0;
            KLinesEntity kLinesEntity_ = null;
            List<Double> cs = new ArrayList<>();
            for (int i = current; i < yz + current; i++) {
                KLinesEntity kLinesEntity = kLinesEntities.get(kLinesEntities.size() - i - 1);
                if (current == i) {
                    kLinesEntity_ = kLinesEntity;
                }
                Double sp = kLinesEntity.getSp();
                cs.add(sp);
                ma += sp;
            }
            List<DataEntity> mbs = res.getMb();
            if (CollectionUtils.isEmpty(mbs)) {
                mbs = new ArrayList<>();
            }
            List<DataEntity> mos = res.getMo();
            if (CollectionUtils.isEmpty(mos)) {
                mos = new ArrayList<>();
            }
            List<DataEntity> ups = res.getUp();
            if (CollectionUtils.isEmpty(ups)) {
                ups = new ArrayList<>();
            }
            List<DataEntity> dns = res.getDn();
            if (CollectionUtils.isEmpty(dns)) {
                dns = new ArrayList<>();
            }
            DataEntity dataEntity_mb = new DataEntity();
            ma = ma / yz;
            dataEntity_mb.setData(ma);
            String date = kLinesEntity_.getDate();
            Double mo = kLinesEntity_.getSp();
            dataEntity_mb.setDate(date);
            mbs.add(dataEntity_mb);

            Double finalMa = ma;
            AtomicReference<Double> sum = new AtomicReference<>(0.0);
            cs.stream().forEach(c -> {
                sum.updateAndGet(v -> v + Math.pow((c - finalMa), 2));
            });
            Double md = Math.sqrt(sum.get() / yz);
            Double up = ma + 2 * md;
            Double dn = ma - 2 * md;
            DataEntity dataEntity_mo = new DataEntity();
            dataEntity_mo.setData(mo);
            dataEntity_mo.setDate(date);
            mos.add(dataEntity_mo);
            DataEntity dataEntity_up = new DataEntity();
            dataEntity_up.setData(up);
            dataEntity_up.setDate(date);
            ups.add(dataEntity_up);
            DataEntity dataEntity_dn = new DataEntity();
            dataEntity_dn.setData(dn);
            dataEntity_dn.setDate(date);
            dns.add(dataEntity_dn);
            res.setMo(mos);
            res.setUp(ups);
            res.setMb(mbs);
            res.setDn(dns);
            return boll(kLinesEntities, yz, current + 1, res);
        }
    }

}
